package com.example;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.PatternSyntaxException;

import org.json.JSONException;
import org.json.JSONObject;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Handler;
import android.util.Log;

import com.example.DatabaseConstants.Configurations;
import com.example.singletones.NotificationCaller;
import com.example.singletones.SQLHelper;
import com.example.singletones.userSettings;

public class Logger {

	private SQLiteDatabase db = null;
	private SQLHelper mSQLHelper;
	private final Handler mHandler = new Handler();
	private static HttpURLConnection httpConn;
	private static int mLastID = -1;
	private static int mTlastID = -1;

	private static final String MainEventsTableName = "MainEvents";

	public Logger() {
		mSQLHelper = SQLHelper.getInstance();
		db = mSQLHelper.getWritableDatabase();
		mLastID = Integer.parseInt(mSQLHelper.selectConfigData(
				Configurations.ConfigurationName.LastUpdateEventTimeStamp,
				Integer.toString(mLastID)));
		mTlastID = mLastID;

		mHandler.postDelayed(mUpdateTimeTask, 60000);
		sendEvents();
	}

	private final Runnable mUpdateTimeTask = new Runnable() {
		public void run() {
			// mHandler.removeCallbacks(mUpdateTimeTask);
			sendEvents();
			// Log.d("Logger","job");
			mHandler.removeCallbacks(mUpdateTimeTask);
			mHandler.postDelayed(mUpdateTimeTask, 20000);
		}
	};

	public String readLargeEventTableAsJSON() {

		JSONObject MYOBJ = new JSONObject() {
		};
		try {

			try {
				String[] id = new String[1];
				id[0] = null;
				Cursor id_cursor = db
						.rawQuery(
								"select ID from MainEvents order by Time_Event DESC limit 1",
								null);
				while (id_cursor.moveToNext()) {
					id[0] = id_cursor.getString(0);
					mTlastID = Integer.parseInt(id[0]);
				}
				if (id[0] != null) {

					String[] arg = new String[1];
					arg[0] = Integer.toString(mLastID);
					Cursor cursor = db
							.rawQuery(
									"select key_1,value_1,key_2,value_2,key_3,value_3,key_4,value_4,key_5,value_5,key_6,value_6,key_7,value_7,key_8,value_8,strftime('%s', Time_Event, 'localtime') from MainEvents where id > ?",
									arg);

					List<JSONObject> Items = new ArrayList<JSONObject>();

					while (cursor.moveToNext()) {
						JSONObject entry = new JSONObject();
						for (int a = 0; a < cursor.getColumnCount(); a++) {
							String theColumn = cursor.getColumnName(a)
									.replaceAll("(?imx)^(float|string)_", "");
							String theColumnNew = theColumn
									.replaceAll(
											"(?imx)strftime\\('%s',\\s+Time_Event,\\s+'localtime'\\)",
											"Time_Event");
							entry.put(theColumnNew, cursor.getString(a));
						}
						Items.add(entry);
					}
					MYOBJ.put("Items", Items);
					MYOBJ.put("table_name", MainEventsTableName);

				}
			} catch (PatternSyntaxException ex) {
				// Syntax error in the regular expression
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return MYOBJ.toString();
	}

	public boolean sendEvents() {
		NotificationCaller.getInstance().MakeNotif("UPDATED SERVER", "");
		Map<String, String> params = new HashMap<String, String>();
		params.put("table_data", readLargeEventTableAsJSON());
		try {
			userSettings.getInstance();
			userSettings.getInstance();
			sendPostRequest("http://75.98.171.141/upload.php?user="
					+ userSettings.userData.getUserName() + "&hash=1&pass="
					+ userSettings.userData.getPassword(), params);
			String Response = readMultipleLinesRespone();

			if ((Response.indexOf("200 ok") != -1) && (mTlastID > -1)) {
				mLastID = mTlastID;
				String[] args = new String[1];
				args[0] = Integer.toString(mLastID);
				Cursor time_cursor = db
						.rawQuery(
								"select Time_Event from `MainEvents` where ID=? limit 1",
								args);
				String lastDate = "";
				while (time_cursor.moveToNext()) {
					lastDate = (time_cursor.getString(0));
					mSQLHelper
							.insertConfigData(
									Configurations.ConfigurationName.LastUpdateEventTimeStamp,
									lastDate);
				}

				db.execSQL("delete from " + MainEventsTableName
						+ " where Time_Event < date( julianday(date('now'))-1)");

			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			Log.d("problem", e.toString());
		}
		return false;
	}

	public HttpURLConnection sendPostRequest(String requestURL,
			Map<String, String> params) throws IOException {
		URL url = new URL(requestURL);
		httpConn = (HttpURLConnection) url.openConnection();
		httpConn.setUseCaches(false);

		httpConn.setDoInput(true); // true indicates the server returns response

		StringBuffer requestParams = new StringBuffer();

		if (params != null && params.size() > 0) {

			httpConn.setDoOutput(true); // true indicates POST request

			// creates the params string, encode them using URLEncoder
			Iterator<String> paramIterator = params.keySet().iterator();
			while (paramIterator.hasNext()) {
				String key = paramIterator.next();
				String value = params.get(key);
				requestParams.append(URLEncoder.encode(key, "UTF-8"));
				requestParams.append("=").append(
						URLEncoder.encode(value, "UTF-8"));
				requestParams.append("&");
			}
			// sends POST data
			Log.d("aa", requestParams.toString());
			OutputStreamWriter writer = new OutputStreamWriter(
					httpConn.getOutputStream());
			writer.write(requestParams.toString());
			writer.flush();
		}

		return httpConn;
	}

	public static String readMultipleLinesRespone() {
		InputStream inputStream = null;
		long length = 0;
		StringBuilder sb = new StringBuilder();
		try {
			if (httpConn != null) {
				inputStream = httpConn.getInputStream();
			} else {
				throw new IOException("Connection is not established.");
			}

			BufferedReader reader = new BufferedReader(new InputStreamReader(
					inputStream));

			String ss = reader.readLine();
			sb.append(ss);
			length += ss.length();
			reader.close();

			return sb.toString();
		} catch (Exception E) {
			return sb.toString();
		}
	}

}
